/*
 * Copyright 2008-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.faxsun.controller.catalog;

import com.faxsun.core.catalog.domain.CountryEnum;
import com.faxsun.core.catalog.domain.FSProductImpl;
import com.faxsun.core.order.service.FSOrderItemServiceImpl;
import com.faxsun.core.order.service.type.FSOrderStatus;
import com.faxsun.web.processor.tool.CheckMobile;
import org.apache.commons.lang3.StringUtils;
import org.broadleafcommerce.common.exception.ServiceException;
import org.broadleafcommerce.common.extension.ExtensionResultHolder;
import org.broadleafcommerce.core.catalog.domain.Category;
import org.broadleafcommerce.core.catalog.domain.Product;
import org.broadleafcommerce.core.order.service.OrderItemService;
import org.broadleafcommerce.core.order.service.type.OrderStatus;
import org.broadleafcommerce.core.search.domain.ProductSearchCriteria;
import org.broadleafcommerce.core.search.domain.ProductSearchResult;
import org.broadleafcommerce.core.search.domain.SearchFacetDTO;
import org.broadleafcommerce.core.search.service.SearchService;
import org.broadleafcommerce.core.web.catalog.CategoryHandlerMapping;
import org.broadleafcommerce.core.web.controller.catalog.BroadleafCategoryController;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * This class works in combination with the CategoryHandlerMapping which finds a
 * category based upon the passed in URL.
 */
@Controller("blCategoryController")
public class CategoryController extends BroadleafCategoryController {

    @Resource(name = "milkSearchService")
    protected SearchService milkSearchService;

    @Resource(name = "blOrderItemService")
    protected OrderItemService orderItemService;

    private List<String> orderStatusesWithQtyCount = Arrays.asList(
        FSOrderStatus.CONFIRMED.getType()
        , FSOrderStatus.DELIVERY.getType()
        , FSOrderStatus.SINGED.getType()
//        , FSOrderStatus.SUBMITTED.getType()
    );

    @SuppressWarnings("unchecked")
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
        throws Exception {
        Category category = (Category) request.getAttribute("category");
        String searchTerm = request.getParameter(ProductSearchCriteria.QUERY_STRING);

		/*
         * Refactoring with getting category info from request attributes
		String path = request.getServletPath();
		if (StringUtils.isBlank(searchTerm)) {
			// FIXME: to introduce the category Enum
			if (path.equals("/mom-and-baby")) {
				return handleSpecificRequest(request, response);
			}
			if ( path.equals("/treasure")) {
				return handleRequestByCatagory(request, response);
			}
		}
		*/

        if (StringUtils.isBlank(searchTerm)) {
            // FIXME: to introduce the category Enum
            if (category.getUrl().equals("/treasure")) {
                return handleRequestByCatagory(request, response);
            }
        }

        ModelAndView model = super.handleRequest(request, response);

        /*
        if (StringUtils.isBlank(searchTerm)) {
            if (path.equals("/high-tech")) {
                model.addObject("meta_key",
                    "智能扫地机器人，智能婴儿摇椅，智能充电宝，创意生活用品，正品irobot，正品mamaroo，Swash，智能干洗，家用干洗机，moov，健身教练仪，智能电子，运动手表");
                model.addObject("meta_description",
                    "范客生活新奇频道为您展现最新的生活潮品！在这里，你不仅能找到最时尚，最新潮的高科技产品，让你的生活更有范。你还能找到那一份让你心动的创意，各种方便实用的创意商品等你来拿！原装正品直邮，让您买的舒心用得放心！");
                model.addObject("pageTitle", "范客生活-新奇-正品低价的生活潮品！");
            }
            if (path.equals("/health")) {
                model.addObject("meta_key",
                    "美国保健品，GNC，健安喜，美国安利，葡萄籽精华素，深海鱼油，进口保健品，Amway，蔓越莓精华素，保健品海淘，保健品代购，胶原蛋白片，海外保健品");
                model.addObject("meta_description",
                    "范客生活健康频道给您和您的家人带来最纯净的保健品！每一瓶保健品都保证了最原始的品质，尽最大可能的保证了营养的天然与纯正。我们不是健康产品的制造者，我们只是大自然的搬运工！专业海外直邮带给你的只是为了一份放心！");
                model.addObject("pageTitle", "范客生活-健康-搬运大自然的馈赠！");
            }
        }
        */

        List<Product> productList = (List<Product>) model.getModel().get(PRODUCTS_ATTRIBUTE_NAME);
        boolean isExistBroad = false;
        if (productList != null) {
            for (Product p : productList) {
                isExistBroad = isExistBroad || ((FSProductImpl) p).getIsBroad();
                if (isExistBroad) {
                    break;
                }
            }
        }
        model.addObject("isExistBroad", isExistBroad);
        model.addObject("quantities",
            ((FSOrderItemServiceImpl) orderItemService).readOrderItemQuantitiesByProductsAndStatus(productList,
                orderStatusesWithQtyCount));

        return model;
    }

    private ModelAndView handleSpecificRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServiceException {
        ModelAndView model = new ModelAndView();
        Category category = (Category) request
            .getAttribute(CategoryHandlerMapping.CURRENT_CATEGORY_ATTRIBUTE_NAME);
        assert (category != null);

        List<SearchFacetDTO> availableFacets = getSearchService().getCategoryFacets(category);
        ProductSearchCriteria searchCriteria = facetService.buildSearchCriteria(request, availableFacets);

        String searchTerm = request.getParameter(ProductSearchCriteria.QUERY_STRING);
        ProductSearchResult result;
        if (StringUtils.isNotBlank(searchTerm)) {
            result = getSearchService().findProductsByCategoryAndQuery(category, searchTerm, searchCriteria);
        } else {
            result = milkSearchService.findProductsByCategory(category, searchCriteria);
        }

        facetService.setActiveFacetResults(result.getFacets(), request);

        Map<CountryEnum, List<Product>> map = new HashMap<CountryEnum, List<Product>>();
        for (Product p : result.getProducts()) {
            FSProductImpl myProduct = (FSProductImpl) p;
            CountryEnum key = myProduct.getCountry();
            List<Product> values = map.get(key);
            if (values == null) {
                values = new ArrayList<Product>();
            }
            values.add(myProduct);

            map.put(key, values);
        }

        List<CountryEnum> countries = new ArrayList<CountryEnum>(map.keySet());
        // TODO: Here, NZ is must existed
        if (countries.contains(CountryEnum.getInstance("NZ"))) {
            countries.remove(CountryEnum.getInstance("NZ"));
            countries.add(0, CountryEnum.getInstance("NZ"));
        }

        List<List<Product>> products = new ArrayList<List<Product>>();
        for (CountryEnum country : countries) {
            products.add(map.get(country));
        }

        model.addObject(CATEGORY_ATTRIBUTE_NAME, category);
        model.addObject("countries", countries);
        model.addObject(PRODUCTS_ATTRIBUTE_NAME, products);
        model.addObject(FACETS_ATTRIBUTE_NAME, result.getFacets());
        model.addObject(PRODUCT_SEARCH_RESULT_ATTRIBUTE_NAME, result);
        model.addObject("meta_description",
            "范客生活母婴频道为您提供最好的海外优质奶粉！来自美国、新西兰和英国的优质奶源，为您的宝宝成长提供最全面营养！海外正品优质奶粉，经过我们的精挑细选，从海外直达您家，品质口碑信得过！");
        model.addObject("meta_key",
            "海淘奶粉，奶粉代购，美国奶粉，英国奶粉，新西兰奶粉，雅培Similac，美赞臣Enfamil，爱他美Aptamil，牛栏Cow&Gate，可瑞康Karicare，正品海外奶粉，优质海外奶粉");
        model.addObject("pageTitle", "范客生活-母婴-海外直邮的健康奶粉！");

        if (result.getProducts() != null) {
            model.addObject(ALL_PRODUCTS_ATTRIBUTE_NAME, new HashSet<Product>(result.getProducts()));
        }

        addDeepLink(model, deepLinkService, category);

        ExtensionResultHolder<String> erh = new ExtensionResultHolder<String>();
        templateOverrideManager.getProxy().getOverrideTemplate(erh, category);

        model.setViewName("catalog/mom-and-baby");
        return model;
    }

    private ModelAndView handleRequestByCatagory(HttpServletRequest request, HttpServletResponse response)
        throws ServiceException {
        ModelAndView model = new ModelAndView();
        Category category = (Category) request
            .getAttribute(CategoryHandlerMapping.CURRENT_CATEGORY_ATTRIBUTE_NAME);
        assert (category != null);

        List<SearchFacetDTO> availableFacets = getSearchService().getCategoryFacets(category);
        ProductSearchCriteria searchCriteria = facetService.buildSearchCriteria(request, availableFacets);

        searchCriteria.setPageSize(Integer.MAX_VALUE);

        String searchTerm = request.getParameter(ProductSearchCriteria.QUERY_STRING);
        ProductSearchResult result;
        if (StringUtils.isNotBlank(searchTerm)) {
            result = getSearchService().findProductsByCategoryAndQuery(category, searchTerm, searchCriteria);
        } else {
            result = getSearchService().findProductsByCategory(category, searchCriteria);
        }

        facetService.setActiveFacetResults(result.getFacets(), request);

        Map<String, List<Product>> treasuresMap = new TreeMap<String, List<Product>>(
            new Comparator<String>() {

                @Override
                public int compare(String o1, String o2) {
                    return -o1.compareTo(o2);
                }
            });
        SimpleDateFormat format = new SimpleDateFormat("yyyyww");

        Iterator<Product> it = result.getProducts().iterator();
        while (it.hasNext()) {
            Product product = it.next();
            String date = format.format(product.getActiveStartDate());

            if (!treasuresMap.containsKey(date)) {
                treasuresMap.put(date, new ArrayList<Product>());
            }
            treasuresMap.get(date).add(product);
        }
        model.addObject("treasuresMap", treasuresMap);
        model.addObject(CATEGORY_ATTRIBUTE_NAME, category);
        model.addObject(PRODUCTS_ATTRIBUTE_NAME, result.getProducts());
        model.addObject(FACETS_ATTRIBUTE_NAME, result.getFacets());
        model.addObject(PRODUCT_SEARCH_RESULT_ATTRIBUTE_NAME, result);
        if (result.getProducts() != null) {
            model.addObject(ALL_PRODUCTS_ATTRIBUTE_NAME, new HashSet<Product>(result.getProducts()));
        }

        addDeepLink(model, deepLinkService, category);

        ExtensionResultHolder<String> erh = new ExtensionResultHolder<String>();
        templateOverrideManager.getProxy().getOverrideTemplate(erh, category);

        if (StringUtils.isNotBlank(erh.getResult())) {
            model.setViewName(erh.getResult());
        } else if (StringUtils.isNotEmpty(category.getDisplayTemplate())) {
            model.setViewName(category.getDisplayTemplate());
        } else {
            model.setViewName("catalog/categoryTreasure");
        }

        return model;
    }

    public SearchService getMilkSearchService() {
        return milkSearchService;
    }

    public void setMilkSearchService(SearchService milkSearchService) {
        this.milkSearchService = milkSearchService;
    }

}
